package jvs.vfs.opt.app;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.util.ArrayList;

import jvs.vfs.IFile;
import jvs.vfs.IFileBaseImpl;
import android.content.Context;

/**
 * @author qiangli
 * 
 */
public class AppFileImpl extends IFileBaseImpl {
	private static ArrayList<ApplicationInfo> all = null;
	//private static ArrayList<ApplicationInfo> faves = null;
	private static ArrayList<ApplicationInfo> recents = null;
	
	synchronized private static void loadAll() {
		if (all == null) {
			all = new ArrayList<ApplicationInfo>();
			Context ctx = (Context) fs.getContext();
			Loader.loadApplications(ctx, all);
		}
	}

//	synchronized private static void loadFave() {
//		if (faves == null) {
//			faves = new ArrayList<ApplicationInfo>();
//			Context ctx = (Context) fs.getContext();
//			Loader.loadFavorites(ctx, faves);
//		}
//	}

	synchronized private static void loadRecent() {
		if (recents == null) {
			recents = new ArrayList<ApplicationInfo>();
		} else {
			recents.clear();
		}
		//always reload recent tasks
		Context ctx = (Context) fs.getContext();
		Loader.loadRecents(ctx, recents);
	}

	private static String[] toArray(ArrayList<ApplicationInfo> list) {
		int sz = list.size();
		String[] sa = new String[sz];
		for (int i = 0; i < sz; i++) {
			ApplicationInfo ai = list.get(i);
			sa[i] = ai.id;
		}
		return sa;
	}

	private ApplicationInfo info = null;
	private boolean isFolder;
	
	/**
	 * @param uri
	 */
	public AppFileImpl(URI uri) {
		super(uri);
		//
		info = null;
		isFolder = true;
		String p = path(uri);
		if (p.equals("/")) {
			//root
			return;
		}
		int t = Types.match(p);
		if (t != -1) {
			//top folders
			return; 
		}
		//app
		isFolder = false;
		loadAll();
		if (all != null) {
			String n = name(p);
			for (ApplicationInfo i: all) {
				if (i.id.equals(n)) {
					info = i;
					return;
				}
			}
		}
	}

	private AppFileImpl(URI uri, ApplicationInfo info) {
		super(uri);
		this.info = info;
		this.isFolder = false;
	}

	@Override
	public boolean canExecute() {
		return (info != null);
	}

	@Override
	public boolean canRead() {
		return true;
	}

	@Override
	public boolean canWrite() {
		return false;
	}

	@Override
	public boolean create() {
		return false;
	}

	@Override
	public boolean delete() {
		return false;
	}

	@Override
	public boolean execute() {
		if (info == null) {
			return false;
		}
		try {
			Context ctx = (Context) fs.getContext();
			if (info.intent == null) {
				return false;
			}
			ctx.startActivity(info.intent);
			return true;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	@Override
	public boolean exists() {
		return true;
	}

	@Override
	public String getDisplayName() {
		if (info != null) {
			return info.title;
		}
		return super.getDisplayName();
	}

	@Override
	public String getContentType() {
		if (info != null) {
			return "application/x-android";
		}
		return super.getContentType();
	}

	@Override
	public Object getIcon() {
		if (info != null) {
			return "/icon/" + info.id; 
		}
		return super.getIcon();
	}

	@Override
	public InputStream getInputStream() {
		return null;
	}

	@Override
	public long getLastModified() {
		return 0;
	}

	@Override
	public long getLength() {
		return 0;
	}

	@Override
	public String getName() {
		if (info != null) {
			return info.id;
		}
		return super.getName();
	}

	@Override
	public OutputStream getOutputStream() {
		return null;
	}

	@Override
	public String getPhoneticName() {
		if (info != null) {
			return info.title;
		}
		return super.getPhoneticName();
	}

	@Override
	public String getSortKey() {
		if (info != null) {
			return info.title;
		}
		return super.getSortKey();
	}

	@Override
	public boolean isDirectory() {
		return (isFolder);
	}

	@Override
	public boolean isEmpty() {
		if (isFolder) {
			return false;
		}
		String p = path(uri);
		int i = Types.match(p);
		switch (i) {
		case Types.RECENT:
			loadRecent();
			return (recents == null || recents.size() == 0);
		case Types.ALL:
			loadAll();
			return (all == null || all.size() == 0);
		}
		return true;
	}

	@Override
	public boolean isFile() {
		return (!isFolder);
	}

	@Override
	public boolean isLocal() {
		return true;
	}

	@Override
	public boolean isNative() {
		return false;
	}

	@Override
	public String[] list() {
		if (!isFolder) {
			return null;
		}
		String p = path(uri);
		if (p.equals("/")) {
			return Types.LIST;
		}
		int i = Types.match(p);
		switch (i) {
		case Types.RECENT:
			loadRecent();
			return toArray(recents);
		case Types.ALL:
			loadAll();
			return toArray(all);
		}
		return null;
	}

	@Override
	public IFile[] listFiles() {
		if (!isFolder) {
			return null;
		}
		String p = path(uri);
		if (p.equals("/")) {
			return super.listFiles();
		}
		int t = Types.match(p);
		ArrayList<ApplicationInfo> al = null;
		switch(t) {
		case Types.ALL:
			loadAll();
			al = all;
			break;
		case Types.RECENT:
			loadRecent();
			al = recents;
			break;
		default:
		}
		if (al == null) {
			return null;
		}
		int len = al.size();
		IFile[] rl = new IFile[len];
		for (int i = 0; i < len; i++) {
			ApplicationInfo ai = al.get(i);
			URI pu = uri.resolve(uri.getPath()+"/" +ai.id);
			rl[i] = new AppFileImpl(pu, ai);
		}
		return rl;
	}

	@Override
	public boolean mkdir() {
		return false;
	}

	@Override
	public boolean move(URI uri) {
		return false;
	}

	@Override
	public void refresh() {
		all = null;
		recents = null;
	}
}
